package cn.com.blueInfo.autoCode.vue;

import lombok.Data;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Component
public class CreateListVue {

    private static final Map<String, String> MAP = Collections.unmodifiableMap(new HashMap<String, String>() {{
        put("bsn", "number");
        put("osm", "person");
        put("sys", "system");
        put("uniflow", "template");
    }});

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void handler() {
        createVueFile();
    }

    private void createVueFile() {
        String baseVueFilePath = "D:\\Development Program\\ProjectCode_idea\\LanxiPavilion\\LanxiPavilion-parent" +
                "\\lanxi-pavilion-vite-vue3\\src\\views\\bpm\\";
        String querySql = "select table_name, table_comment from information_schema.`TABLES` where TABLE_SCHEMA = 'haiyuan_dev'";
        List<Map<String, Object>> resultData = jdbcTemplate.queryForList(querySql);
        List<VueFile> vueFileList = new ArrayList<>();

        for (Map<String, Object> oneData : resultData) {
            String tableName = (String) oneData.get("table_name");
            String tableComment = (String) oneData.get("table_comment");
            String[] tableNames = tableName.split("_");

            VueFile vueFile = new VueFile();

            String modulePath = MAP.get(tableNames[1]);
            vueFile.setFilePath(baseVueFilePath.concat(modulePath).concat(File.separator));
            vueFile.setFileContent(getFileContent(getScriptContent(), getTemplateContent(tableName), getStyleContent()));
            vueFile.setFileName(getFileName(tableNames));
            vueFileList.add(vueFile);
        }
        writeFile(vueFileList);
    }

    private String getTemplateContent(String tableName) {
        String querySql = "select COLUMN_NAME, COLUMN_TYPE, COLUMN_COMMENT from information_schema.`COLUMNS` \n" +
                "where TABLE_SCHEMA = 'haiyuan_dev' " +
                "and TABLE_NAME = '" + tableName + "'";
        String resultContent = "  <el-table\n" +
                "    :data=\"tableData\"\n" +
                "    :stripe=\"true\"\n" +
                "    :border=\"true\"\n" +
                "  >\n" +
                "    <el-table-column type=\"selection\" width=\"40\" />\n";
        List<Map<String, Object>> resultData = jdbcTemplate.queryForList(querySql);
        for (Map<String, Object> oneData : resultData) {
            String columnName = (String) oneData.get("COLUMN_NAME");
            if (isWriteColumn(columnName)) continue;
            columnName = getColumnName(columnName);
//            String columnType = (String) oneData.get("COLUMN_TYPE");
            String columnComment = (String) oneData.get("COLUMN_COMMENT");
            columnComment = columnComment.contains("：") ? columnComment.substring(0, columnComment.indexOf("：")) :
                    columnComment.contains("（") ? columnComment.substring(0, columnComment.indexOf("（")) : columnComment;

            resultContent = resultContent.concat("    <el-table-column prop=\"" + columnName + "\" label=\"" + columnComment + "\" />\n");

        }

        resultContent = resultContent.concat("    <el-table-column label=\"操作\">\n" +
                "      <template #default>\n" +
                "        <el-button link type=\"primary\" size=\"small\">修改</el-button>\n" +
                "        <el-button link type=\"primary\" size=\"small\">删除</el-button>\n" +
                "      </template>\n" +
                "    </el-table-column>\n" +
                "  </el-table>\n" +
                "  <br/>\n" +
                "  <BasePagination :pageInfo=\"pageInfo\" @pagesEvent=\"handlePagesEvent\"></BasePagination>\n");
        return resultContent;
    }

    private String getScriptContent() {
        return "import {onMounted, ref} from \"vue\";\n" +
                "import BasePagination from \"@/components/common/BasePagination.vue\";\n" +
                "// 表格数据\n" +
                "const tableData = ref([])\n" +
                "// 分页数据\n" +
                "const pageInfo = ref({\n" +
                "  current: 1,\n" +
                "  pages: 0,\n" +
                "  size: 20,\n" +
                "  total: 0\n" +
                "})\n" +
                "\n" +
                "const getPageData = async (page, size) => {\n" +
                "  const response = await null\n" +
                "  const responseData = response.data.data\n" +
                "  tableData.value = responseData.records\n" +
                "  pageInfo.value.current = responseData.current\n" +
                "  pageInfo.value.pages = responseData.pages\n" +
                "  pageInfo.value.size = responseData.size\n" +
                "  pageInfo.value.total = responseData.total\n" +
                "}\n" +
                "\n" +
                "const handlePagesEvent = (page, size) => {\n" +
                "  getPageData(page, size)\n" +
                "}\n" +
                "\n" +
                "onMounted(() => {\n" +
                "  getPageData(1, 20)\n" +
                "})";
    }

    private String getStyleContent() {
        return ".el-table {\n" +
                "  height: $table-height;\n" +
                "  width: 100%;\n" +
                "}";
    }

    private void writeFile(List<VueFile> vueFileList) {
        try {
            for (VueFile vueFile : vueFileList) {
                String filePath = vueFile.getFilePath().concat(vueFile.getFileName());
                FileUtils.writeStringToFile(new File(filePath), vueFile.getFileContent(), StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String getFileName(String[] tableNames) {
        String fileName = "";
        for (int t_i = 2, t_len = tableNames.length; t_i < t_len; t_i++) {
            String name = tableNames[t_i];
            fileName = fileName.concat(StringUtils.capitalize(name));
        }
        fileName = StringUtils.uncapitalize(fileName);
        return fileName.concat(File.separator).concat("List.vue");
    }

    private String getColumnName(String columnName) {
        String[] columnNames = columnName.split("_");
        String resultName = "";
        for (String name : columnNames) {
            resultName = resultName.concat(StringUtils.capitalize(name));
        }
        resultName = StringUtils.uncapitalize(resultName);
        return resultName;
    }

    private String getModuleName(String moduleName, String tableComment) {
        return "  <div>" + moduleName.concat("-").concat(tableComment.substring(0, tableComment.length() - 1)) + "</div>\n";
    }

    private String getFileContent(String scriptContent,  String templateContent, String styleContent) {
        return "<script setup>\n" +
                scriptContent + "\n" +
                "</script>\n" +
                "\n" +
                "<template>\n" +
                templateContent +
                "</template>\n" +
                "\n" +
                "<style scoped lang=\"scss\">\n" +
                styleContent + "\n" +
                "</style>";
    }

    @Data
    private static class VueFile {
        private String fileName;
        private String filePath;
        private String fileContent;
    }

    private boolean isWriteColumn(String columnName) {
        String[] fields = {
                "application_id",
                "create_time",
                "create_user_id",
                "deleted",
                "delete_time",
                "delete_user_id",
                "extend1",
                "extend2",
                "extend3",
                "id",
                "order_number",
                "remark",
                "status",
                "tenant_id",
                "update_time",
                "update_user_id"
        };
        for (String field : fields) {
            if (field.equals(columnName))
                return true;
        }
        return false;
    }

}
